# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Codec:

    def serialize(self, root):
        """Encodes a tree to a single string.
        
        :type root: TreeNode
        :rtype: str
        """
        if not root:
            return ''

        q = deque([root])
        ans = list()
        while q:
            node = q.popleft()
            if not node:
                ans.append('#')
            else:
                ans.append(str(node.val))
                q.append(node.left)
                q.append(node.right)

        return '.'.join(ans)


    def deserialize(self, data):
        """Decodes your encoded data to tree.
        
        :type data: str
        :rtype: TreeNode
        """
        nodes = data.split('.')
        if not nodes or nodes[0] == '#' or nodes[0] == '':
            return None

        root = TreeNode(int(nodes[0]))
        q = deque([root, root])
        i = 1
        left = 1
        while q:
            node = q.popleft()
            if nodes[i] != '#':
                if left:
                    node.left = TreeNode(int(nodes[i]))
                    q.append(node.left)
                    q.append(node.left)
                else:
                    node.right = TreeNode(int(nodes[i]))
                    q.append(node.right)
                    q.append(node.right)
            if left:
                left = 0
            else:
                left = 1
            
            i += 1

        return root
        

# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.deserialize(codec.serialize(root))
